feat: add support to wire webhooks from orchestrator to emitter workflows#70
feat: add support to wire webhooks from orchestrator to emitter workflows#70
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c0fdc2ec99
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Args: []interface{}{orchestrator.WorkflowInput{ | ||
| ResourceTypes: cfg.ResourceTypes, | ||
| ResourceTypes: cfg.ResourceTypes, | ||
| EmitterWebhookURL: cfg.EmitterWebhookURL, |
There was a problem hiding this comment.
Propagate webhook URL for existing schedules
EnsureSchedule only applies EmitterWebhookURL in the create-time action args, but the already-existing-schedule path does not compare or rewrite workflow args (it exits early when cron/jitter match, and update only touches spec/task queue). In an upgraded deployment where the schedule already exists, setting EMITTER_WEBHOOK_URL later will not reach scheduled orchestrator runs, so Stage 3 webhook notifications never fire unless the schedule is recreated manually.
Useful? React with 👍 / 👎.
|
🤖 Concern on the mock-inventory fallback in The The PR description says "Production paths always set the Wiz secrets, so this branch is dev-only" — but nothing in the code enforces that. Any prod misconfiguration (rotated secret, IRSA mis-binding, partial rollout, secret-mount race on pod start) will now silently emit fabricated 1.0.0 findings into S3 instead of failing fast. Those snapshots feed every downstream consumer, including the new emitter webhook this PR wires up. Worst case: a green compliance dashboard built on synthetic data, with no obvious signal that the underlying inventory source is broken. Suggested mitigation: gate the mock fallback on an explicit opt-in (e.g. |
|
🤖 Mock inventory Engine: resourceCfg.Type,For Aurora, Worth verifying against the adapter dispatch before claiming the e2e screenshot demonstrates a working detector→emitter path — it may be exercising the wire but not the classification. |
|
🤖 Constructor-signature inconsistency in
Pick one. Either add the URL as a positional arg to |
|
🤖 payload, err := json.Marshal(struct {
SnapshotID string `json:"snapshot_id,omitempty"`
}{SnapshotID: input.SnapshotID})In the real flow, Stage 3 only runs after Two options:
Right now it reads like defensive code for a case that can't happen, which adds confusion for future readers. |
2c74eb4 to
3f2f852
Compare
…with optional emitter
…with optional emitter
…with optional emitter
…t; same make compose-* interface for everyone
What and Why?
Adds the detector → emitter webhook so the
OrchestratorWorkflowcan notify a downstream emitter as soon as a snapshot is persisted, instead of relying on the emitter's own cron.No breaking changes. No schema changes. Every observable surface is purely additive; defaults reproduce prior behavior.
Auth model: wire-only. Network isolation between detector and emitter is a deployment concern (Kubernetes NetworkPolicy, Istio AuthorizationPolicy, mTLS, etc.), not enforced at the app layer.
What's new (production code)
pkg/workflow/orchestrator/notify.go—NotifyEmitteractivity. POSTs{"snapshot_id": "<id>"}to<EmitterWebhookURL>/trigger-actwith an injectableHTTPDoerso tests can swap in a fake. Default client uses a 10s timeout.snapshot_idis always sent (noomitempty— Stage 3 only runs afterCreateSnapshotpopulates the ID).pkg/workflow/orchestrator/workflow.go—OrchestratorWorkflowgains Stage 3 (NotifyEmitter), invoked only whenEmitterWebhookURLis non-empty. Failures are non-fatal: the snapshot is already durable in S3, so a transient emitter outage just delays emission and Temporal's retry policy handles the rest.pkg/workflow/orchestrator/activities.go— optionalHTTPDoerfield onActivitiesfor test injection.pkg/scan/scan.go—NewTriggerandNewTriggerWithStarterkeep their 3-arg shape; the optional emitter webhook URL is set with theWithEmitterWebhookURLfunctional option (consistent across both constructors).WorkflowInput.EmitterWebhookURLis forwarded into the orchestrator workflow input.pkg/schedule/schedule.go—Config.EmitterWebhookURLplumbed into the scheduled workflow input. The "schedule already exists" update path now also rewritesAction.Argsso a newly-setEMITTER_WEBHOOK_URL(or changedResourceTypes/TaskQueue) propagates to existing schedules without manual recreation.cmd/server/main.go—EMITTER_WEBHOOK_URLenv flag, registersNotifyEmitteractivity, threads the URL through the schedule and the admin/scantrigger.INVENTORY_FALLBACKenv flag (default""= fail-fast). Only when explicitly set tomockdoes the wiz-source branch substitute a synthetic resource; default is the original loud-fail behavior. Never set this in production — a missing Wiz secret would otherwise silently emit fabricated1.0.0findings.Enginefield is keyed offresourceCfg.ID(e.g.aurora-postgresql) so endoflife.date adapters resolve a real lifecycle instead ofUNKNOWN.cmd/cli/main.go— uses the 3-argNewTrigger; CLI runs stay detector-only (no webhook).Local testability (production-safe; defaults preserve current behavior)
pkg/snapshot/memory_store.go— in-processStorefor laptop dev / CI smoke tests. Selectable viaSNAPSHOT_STORE=memory(default remainss3). Lets the orchestrator's Stage 2 succeed without AWS credentials.docker-compose.yaml— extended with an optionalemitterservice (gated by thewith-emitterCompose profile), env wiring for the new flags, andEMITTER_PATHbuild-context override (defaults to../version-guard-emitter). Devs without the emitter source can leave the profile off.Makefile— new targets:compose-up/compose-up-detector/compose-down/compose-logs/compose-e2e— full-stack local dev via Docker Compose.temporal-docker,webhook-e2e,webhook-e2e-smoke— Docker-based Temporal CLI / curl helpers (nobrew install temporalneeded).make devis nowentr-optional (auto-reload whenentris on$PATH, otherwise plaingo run).Documentation
README.md— new env-var rows forSNAPSHOT_STORE,INVENTORY_FALLBACK,EMITTER_WEBHOOK_URL; new "Optional: out-of-process webhook emitter" subsection under docker-compose; new §2 "Out-of-process Emitter via Webhook (Optional)" under Extending Version Guard, with a comparison table to clarify when in-process vs out-of-process emitters fit.ARCHITECTURE.md— Stage 3 added to theOrchestratorWorkflowexample.Backwards compatibility
pkg/scanconstructors keep their 3-arg shape; the URL is set via the new functional optionWithEmitterWebhookURL. Internal Go API only — no external consumers.WorkflowInput,Config, andActivitiesonly gain new optional fields; zero-values reproduce prior behavior. Forward replay is deterministic because Stage 3 is gated onEmitterWebhookURL != "", which old executions never have.EMITTER_WEBHOOK_URL,SNAPSHOT_STORE,INVENTORY_FALLBACK) all have safe defaults that preserve legacy behavior.Tests
Full unit suite green (
pkg/scan,pkg/schedule,pkg/snapshot,pkg/workflow/orchestrator,pkg/workflow/detection).NotifyEmitterhas 6 tests covering success, 4xx, 5xx, network error, missing URL, and unparseable-but-successful body.pkg/schedulehas a regression test (TestEnsureSchedule_Update_RefreshesActionArgs) verifyingEmitterWebhookURL(andResourceTypes/TaskQueue) propagates into existing schedules.Local e2e workflow test confirmation